package com.luqili.utils.pub.consts;

import cn.hutool.core.util.ReflectUtil;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 * 常量接口
 *
 * @param <T> 指定常量泛型
 * @author luqili
 */
public interface LuConstRoot<T extends Serializable> {
    /**
     * 获取名称,无对应值时返回 ""
     *
     * @param val 常量值
     * @return 常量名称
     */
    String getName(T val);

    /**
     * 获取分类名称
     *
     * @return 类型名
     */
    default String getCategoryName() {
        return "";
    }

    /**
     * 是否允许用户新增，默认不允许
     *
     * @return Boolean
     */
    default boolean isUserAppend() {
        return false;
    }

    /**
     * 获取名称
     *
     * @param obj 常量值
     * @return 常量名称(参数为Null或不存在该常量 ， 返回Null)
     */
    default String getNameByObject(Object obj) {
        T t = convertByObject(obj);
        return getName(t);
    }

    /**
     * 通过Object转换为当前常量值，不能转换抛出异常
     *
     * @param obj Object类型的参数
     * @return T
     */
    default T convertByObject(Object obj) {
        try {
            return (T) obj;
        } catch (Exception e) {
            throw new LuConstException("未实现数据转换：" + this.getClass().getSimpleName());
        }
    }

    /**
     * 根据名获取常量值
     *
     * @param name 常量名称
     * @return 常量值
     */
    default T getValue(String name) {
        throw new LuConstException("未实现该功能：根据名获取常量值" + this.getClass().getSimpleName());
    }

    /**
     * 获取所有常量
     *
     * @return 常量数组
     */
    default Set<T> getValues() {
        Field[] fields = ReflectUtil.getFields(this.getClass());
        Set<T> vs = new TreeSet<>();
        for (Field field : fields) {
            if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) {
                Object value = ReflectUtil.getStaticFieldValue(field);
                vs.add((T) value);
            }
        }
        return vs;
    }

    /**
     * 获取名称列表信息
     *
     * @return
     */
    default Set<String> getNames() {
        Set<T> values = getValues();
        Set<String> names = new HashSet<>();
        values.forEach(T -> {
            names.add(getName(T));
        });
        return names;
    }

    /**
     * 获取颜色,无对应值时返回 ""
     *
     * @param val 常量值
     * @return 常量颜色
     */
    default String getColorByObject(Object val) {
        T t = convertByObject(val);
        return getColor(t);
    }

    /**
     * 获取颜色,无对应值时返回 ""
     *
     * @param val 常量值
     * @return 常量颜色
     */
    default String getColor(T val) {
        int v;
        if (val instanceof Number) {
            Number num = (Number) val;
            v = num.intValue();
        } else {
            v = val.hashCode();
        }
        switch (v % 10) {
            case 0:
                return LuConstColorHex.GREEN;
            case 1:
                return LuConstColorHex.TEAL;
            case 2:
                return LuConstColorHex.BLUE;
            case 3:
                return LuConstColorHex.DEEP_SKY_BLUE;
            case 4:
                return LuConstColorHex.SKY_BLUE;
            case 5:
                return LuConstColorHex.ROYAL_BLUE;
            case 6:
                return LuConstColorHex.PINK;
            case 7:
                return LuConstColorHex.ORANGE_RED;
            case 8:
                return LuConstColorHex.MAGENTA;
            case 9:
                return LuConstColorHex.RED;
            default:
                break;
        }
        return LuConstColorHex.DIM_GRAY;
    }

    /**
     * 获取展示的HTML标签
     *
     * @param val 常量值
     * @return 常量HTML标签封装
     */
    default String getHtmlSpan(T val) {
        return "<span style=\"color:" + getColor(val) + ";\">" + getName(val) + "</span>";
    }

    /**
     * 获取展示的HTML标签
     *
     * @param val 常量值
     * @return 常量HTML标签封装
     */
    default String getHtmlSpanByObject(Object val) {
        try {
            T t = convertByObject(val);
            return getHtmlSpan(t);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 获取指定的常量信息
     *
     * @param val
     * @return
     */
    default LuConstInfoEntity<T> getConstInfo(T val) {
        LuConstInfoEntity<T> entity = new LuConstInfoEntity<T>();
        entity.setValue(val);
        entity.setName(getName(val));
        entity.setColor(getColor(val));
        return entity;

    }


    /**
     * 对每个常量标记的备注信息
     *
     * @param val
     * @return
     */
    default String getRemark(T val) {
        return "";
    }

}
